// Cloudflare R2 sync functionality
// Replace Google Drive sync with R2 Workers API

let r2_config = {
    worker_url: '',  // To be set by user
    api_token: '',   // To be set by user
    bucket_name: 'words-discoverer-sync'
};

function report_sync_failure(error_msg) {
    console.error('R2 Sync Error:', error_msg);
    chrome.storage.local.set({"wd_last_sync_error": error_msg}, function () {
        chrome.runtime.sendMessage({'sync_feedback': 1});
    });
}

function report_sync_success() {
    var sync_date = new Date();
    var sync_time = sync_date.getTime();
    chrome.storage.local.set({
        "wd_last_sync_error": null,
        "wd_last_sync": sync_time
    }, function () {
        chrome.runtime.sendMessage({'sync_feedback': 1});
    });
}

// Create directory (bucket path prefix) in R2
function create_r2_directory(dir_name, success_cb) {
    // R2 doesn't need explicit directory creation, just use path prefix
    success_cb(dir_name);
}

// Upload file to R2 via Workers API
function upload_r2_file(file_path, content, success_cb) {
    if (!r2_config.worker_url || !r2_config.api_token) {
        report_sync_failure('R2 configuration not set. Please configure Worker URL and API token.');
        return;
    }

    const headers = {
        'Authorization': 'Bearer ' + r2_config.api_token,
        'Content-Type': 'text/plain'
    };

    fetch(r2_config.worker_url + '/upload', {
        method: 'PUT',
        headers: headers,
        body: JSON.stringify({
            key: file_path,
            content: content
        })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Upload failed: ' + response.status);
        }
        return response.json();
    })
    .then(data => {
        if (data.success) {
            success_cb();
        } else {
            report_sync_failure('Upload failed: ' + (data.error || 'Unknown error'));
        }
    })
    .catch(error => {
        report_sync_failure('Network error during upload: ' + error.message);
    });
}

// Download file from R2 via Workers API
function download_r2_file(file_path, success_cb) {
    if (!r2_config.worker_url || !r2_config.api_token) {
        report_sync_failure('R2 configuration not set. Please configure Worker URL and API token.');
        return;
    }

    const headers = {
        'Authorization': 'Bearer ' + r2_config.api_token
    };

    fetch(r2_config.worker_url + '/download?key=' + encodeURIComponent(file_path), {
        method: 'GET',
        headers: headers
    })
    .then(response => {
        if (!response.ok) {
            if (response.status === 404) {
                // File not found, create new
                success_cb(null);
                return;
            }
            throw new Error('Download failed: ' + response.status);
        }
        return response.text();
    })
    .then(content => {
        success_cb(content);
    })
    .catch(error => {
        report_sync_failure('Network error during download: ' + error.message);
    });
}

// List files in R2 directory via Workers API
function list_r2_files(prefix, success_cb) {
    if (!r2_config.worker_url || !r2_config.api_token) {
        report_sync_failure('R2 configuration not set. Please configure Worker URL and API token.');
        return;
    }

    const headers = {
        'Authorization': 'Bearer ' + r2_config.api_token
    };

    fetch(r2_config.worker_url + '/list?prefix=' + encodeURIComponent(prefix), {
        method: 'GET',
        headers: headers
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('List failed: ' + response.status);
        }
        return response.json();
    })
    .then(data => {
        if (data.success) {
            success_cb(data.files || []);
        } else {
            report_sync_failure('List failed: ' + (data.error || 'Unknown error'));
        }
    })
    .catch(error => {
        report_sync_failure('Network error during list: ' + error.message);
    });
}

function apply_cloud_vocab(entries) {
    var sync_date = new Date();
    var sync_time = sync_date.getTime();
    var new_state = {
        "wd_last_sync_error": null,
        "wd_user_vocabulary": entries,
        "wd_user_vocab_added": {},
        "wd_user_vocab_deleted": {},
        "wd_last_sync": sync_time
    };
    chrome.storage.local.set(new_state, function () {
        chrome.runtime.sendMessage({'sync_feedback': 1});
    });
}

// Parse vocabulary from text format
function parse_vocabulary(content) {
    if (!content) return [];
    return content.split('\n').filter(line => line.trim()).map(line => line.trim());
}

// Serialize vocabulary to text format
function serialize_vocabulary(vocab_set) {
    return Object.keys(vocab_set).join('\n');
}

// Convert list to set (object)
function list_to_set(vocab_list) {
    var set = {};
    for (var i = 0; i < vocab_list.length; i++) {
        set[vocab_list[i]] = 1;
    }
    return set;
}

// Subtract words from set
function substract_from_set(target_set, subtract_set) {
    if (!subtract_set) return;
    for (var word in subtract_set) {
        delete target_set[word];
    }
}

// Add words to set
function add_to_set(target_set, add_set) {
    if (!add_set) return;
    for (var word in add_set) {
        target_set[word] = 1;
    }
}

// Main sync vocabulary function
function sync_vocabulary_r2(dir_path, vocab) {
    var vocab_file_path = dir_path + '/' + vocab.name + '.txt';
    
    function merge_and_upload_vocab(file_content) {
        vocab_list = parse_vocabulary(file_content);
        var entries = list_to_set(vocab_list);
        substract_from_set(entries, vocab.deleted);
        add_to_set(entries, vocab.added);
        merged_content = serialize_vocabulary(entries);

        function set_merged_vocab() {
            apply_cloud_vocab(entries);
        }
        
        upload_r2_file(vocab_file_path, merged_content, set_merged_vocab);
    }

    download_r2_file(vocab_file_path, merge_and_upload_vocab);
}

// Backup vocabulary
function backup_vocabulary_r2(dir_path, vocab, success_cb) {
    var backup_file_path = dir_path + '/' + vocab.name + '_backup_' + Date.now() + '.txt';
    var backup_content = serialize_vocabulary(vocab.all);
    upload_r2_file(backup_file_path, backup_content, success_cb);
}

// Perform full sync
function perform_full_sync_r2(vocab) {
    var dir_name = "Words_Discoverer_Sync";
    
    function backup_and_sync_vocabulary() {
        function sync_vocabulary_wrap() {
            sync_vocabulary_r2(dir_name, vocab);
        }
        backup_vocabulary_r2(dir_name, vocab, sync_vocabulary_wrap);
    }

    backup_and_sync_vocabulary();
}

// Main sync function
function sync_user_vocabularies_r2() {
    chrome.storage.local.get(['wd_user_vocabulary', 'wd_user_vocab_added', 'wd_user_vocab_deleted'], function(result) {
        var vocab = {
            name: 'user_vocabulary',
            all: result.wd_user_vocabulary || {},
            added: result.wd_user_vocab_added || {},
            deleted: result.wd_user_vocab_deleted || {}
        };
        perform_full_sync_r2(vocab);
    });
}

// Start R2 sync sequence
function start_r2_sync_sequence(interactive_authorization) {
    // Get R2 configuration
    chrome.storage.local.get(['wd_r2_worker_url', 'wd_r2_api_token'], function(result) {
        if (!result.wd_r2_worker_url || !result.wd_r2_api_token) {
            report_sync_failure('R2 configuration missing. Please set Worker URL and API token in settings.');
            return;
        }
        
        r2_config.worker_url = result.wd_r2_worker_url;
        r2_config.api_token = result.wd_r2_api_token;
        
        sync_user_vocabularies_r2();
    });
}

// Check if sync is needed and perform it
function sync_if_needed_r2() {
    var req_keys = ['wd_last_sync', 'wd_r2_sync_enabled', 'wd_last_sync_error'];
    chrome.storage.local.get(req_keys, function(result) {
        var wd_last_sync = result.wd_last_sync;
        var wd_r2_sync_enabled = result.wd_r2_sync_enabled;
        var wd_last_sync_error = result.wd_last_sync_error;
        
        if (!wd_r2_sync_enabled || wd_last_sync_error != null) {
            return;
        }
        
        var cur_date = new Date();
        var mins_passed = (cur_date.getTime() - wd_last_sync) / (60 * 1000);
        var sync_period_mins = 30;
        
        if (mins_passed >= sync_period_mins) {
            chrome.runtime.sendMessage({wdm_request: "r2_sync", interactive_mode: false});
        }
    });
}